using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ThridGroup.ERP.DTO;
using ThridGroup.ERP.WarehouseManagement;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;

namespace ThridGroup.ERP.Application.WarehouseManagement
{
    /// <summary>
    /// 仓库设置服务实现
    /// </summary>
    public class WarehouseSettingService : IWarehouseSettingService
    {
        private readonly IRepository<WarehouseSettingModel, int> _warehouseSettingRepository;
        private readonly ILogger<WarehouseSettingService> _logger;

        public WarehouseSettingService(
            IRepository<WarehouseSettingModel, int> warehouseSettingRepository,
            ILogger<WarehouseSettingService> logger)
        {
            _warehouseSettingRepository = warehouseSettingRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取所有仓库设置
        /// </summary>
        public async Task<List<WarehouseSettingDto>> GetWarehouseSettings()
        {
            try
            {
                _logger.LogInformation("开始获取所有仓库设置");
                
                // 从仓储获取所有仓库设置
                var entities = await _warehouseSettingRepository.GetListAsync();
                
                // 转换为DTO
                var result = entities.Select(e => new WarehouseSettingDto
                {
                    Id = e.Id,
                    DepotCode = e.DepotCode,
                    DepotName = e.DepotName,
                    Location = e.Location,
                    Area = e.Area,
                    Head = e.Head,
                    Remark = e.Remark
                }).ToList();

                _logger.LogInformation($"获取所有仓库设置完成，共 {result.Count} 条记录");
                
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有仓库设置失败");
                throw new Exception($"获取所有仓库设置失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 分页获取仓库设置
        /// </summary>
        public async Task<(List<WarehouseSettingDto> data, int total)> GetWarehouseSettingsPaged(
            string depotCode = null, 
            string depotName = null, 
            string location = null, 
            int page = 1, 
            int limit = 10)
        {
            try
            {
                _logger.LogInformation($"开始分页获取仓库设置列表，页码：{page}，每页数量：{limit}");

                // 获取所有数据
                var allData = await GetWarehouseSettings();

                // 应用筛选条件
                if (!string.IsNullOrWhiteSpace(depotCode))
                {
                    allData = allData.Where(x => x.DepotCode.Contains(depotCode, StringComparison.OrdinalIgnoreCase)).ToList();
                }

                if (!string.IsNullOrWhiteSpace(depotName))
                {
                    allData = allData.Where(x => x.DepotName.Contains(depotName, StringComparison.OrdinalIgnoreCase)).ToList();
                }

                if (!string.IsNullOrWhiteSpace(location))
                {
                    allData = allData.Where(x => x.Location.Contains(location, StringComparison.OrdinalIgnoreCase)).ToList();
                }

                var total = allData.Count;

                // 分页
                var pagedData = allData
                    .Skip((page - 1) * limit)
                    .Take(limit)
                    .ToList();

                _logger.LogInformation($"分页获取完成，总记录数：{total}，当前页记录数：{pagedData.Count}");
                
                return (pagedData, total);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "分页获取仓库设置列表失败");
                throw new Exception($"分页获取仓库设置列表失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 根据ID获取仓库设置
        /// </summary>
        public async Task<WarehouseSettingDto> GetWarehouseSetting(int id)
        {
            try
            {
                _logger.LogInformation($"开始获取仓库设置，ID：{id}");
                
                // 从仓储获取指定ID的仓库设置
                var entity = await _warehouseSettingRepository.GetAsync(id);
                
                if (entity == null)
                {
                    _logger.LogWarning($"未找到ID为 {id} 的仓库设置");
                    return null;
                }
                
                // 转换为DTO
                var result = new WarehouseSettingDto
                {
                    Id = entity.Id,
                    DepotCode = entity.DepotCode,
                    DepotName = entity.DepotName,
                    Location = entity.Location,
                    Area = entity.Area,
                    Head = entity.Head,
                    Remark = entity.Remark
                };
                
                _logger.LogInformation($"获取仓库设置成功，ID：{id}");
                
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取仓库设置失败，ID：{id}");
                throw new Exception($"获取仓库设置失败，ID：{id}，错误信息：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 添加仓库设置
        /// </summary>
        public async Task<int> AddWarehouseSetting(WarehouseSettingDto dto)
        {
            try
            {
                _logger.LogInformation("开始添加仓库设置");
                
                // 检查编码是否已存在
                var existingEntity = await _warehouseSettingRepository.FirstOrDefaultAsync(x => x.DepotCode == dto.DepotCode);
                
                if (existingEntity != null)
                {
                    _logger.LogWarning($"仓库编码 {dto.DepotCode} 已存在");
                    throw new Exception($"仓库编码 {dto.DepotCode} 已存在");
                }
                
                // 创建实体
                var entity = new WarehouseSettingModel
                {
                    DepotCode = dto.DepotCode,
                    DepotName = dto.DepotName,
                    Location = dto.Location,
                    Area = dto.Area,
                    Head = dto.Head,
                    Remark = dto.Remark
                };
                
                // 添加到仓储
                var result = await _warehouseSettingRepository.InsertAsync(entity);
                
                _logger.LogInformation($"添加仓库设置成功，ID：{result.Id}");
                
                return result.Id;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "添加仓库设置失败");
                throw new Exception($"添加仓库设置失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 更新仓库设置
        /// </summary>
        public async Task<int> UpdateWarehouseSetting(WarehouseSettingDto dto)
        {
            try
            {
                _logger.LogInformation($"开始更新仓库设置，ID：{dto.Id}");
                
                // 检查ID是否存在
                var entity = await _warehouseSettingRepository.GetAsync(dto.Id);
                
                if (entity == null)
                {
                    _logger.LogWarning($"未找到ID为 {dto.Id} 的仓库设置");
                    throw new Exception($"未找到ID为 {dto.Id} 的仓库设置");
                }
                
                // 检查编码是否已存在(排除自身)
                var existingEntity = await _warehouseSettingRepository.FirstOrDefaultAsync(x => x.DepotCode == dto.DepotCode && x.Id != dto.Id);
                
                if (existingEntity != null)
                {
                    _logger.LogWarning($"仓库编码 {dto.DepotCode} 已存在于其他记录中");
                    throw new Exception($"仓库编码 {dto.DepotCode} 已存在于其他记录中");
                }
                
                // 更新实体
                entity.DepotCode = dto.DepotCode;
                entity.DepotName = dto.DepotName;
                entity.Location = dto.Location;
                entity.Area = dto.Area;
                entity.Head = dto.Head;
                entity.Remark = dto.Remark;
                
                // 更新到仓储
                await _warehouseSettingRepository.UpdateAsync(entity);
                
                _logger.LogInformation($"更新仓库设置成功，ID：{dto.Id}");
                
                return dto.Id;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新仓库设置失败，ID：{dto?.Id}");
                throw new Exception($"更新仓库设置失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 删除仓库设置
        /// </summary>
        public async Task DeleteWarehouseSetting(int id)
        {
            try
            {
                _logger.LogInformation($"开始删除仓库设置，ID：{id}");
                
                // 检查ID是否存在
                var entity = await _warehouseSettingRepository.FindAsync(id);
                
                if (entity == null)
                {
                    _logger.LogWarning($"未找到ID为 {id} 的仓库设置");
                    throw new Exception($"未找到ID为 {id} 的仓库设置");
                }
                
                // 从仓储中删除
                await _warehouseSettingRepository.DeleteAsync(id);
                
                _logger.LogInformation($"删除仓库设置成功，ID：{id}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除仓库设置失败，ID：{id}");
                throw new Exception($"删除仓库设置失败，ID：{id}，错误信息：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 根据ID获取仓库设置
        /// </summary>
        public async Task<WarehouseSettingDto> GetByIdAsync(int id)
        {
            try
            {
                _logger.LogInformation($"开始获取仓库设置(ById)，ID：{id}");
                
                // 从仓储获取指定ID的仓库设置
                var entity = await _warehouseSettingRepository.GetAsync(id);
                
                if (entity == null)
                {
                    _logger.LogWarning($"未找到ID为 {id} 的仓库设置");
                    return null;
                }
                
                // 转换为DTO
                var result = new WarehouseSettingDto
                {
                    Id = entity.Id,
                    DepotCode = entity.DepotCode,
                    DepotName = entity.DepotName,
                    Location = entity.Location,
                    Area = entity.Area,
                    Head = entity.Head,
                    Remark = entity.Remark
                };
                
                _logger.LogInformation($"获取仓库设置(ById)成功，ID：{id}");
                
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取仓库设置(ById)失败，ID：{id}");
                throw new Exception($"获取仓库设置(ById)失败，ID：{id}，错误信息：{ex.Message}", ex);
            }
        }
    }
} 